package com.cirnoworks.uhs.server;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.Selector;

import com.cirnoworks.uhs.AddressCache;
import com.cirnoworks.uhs.AddressKey;
import com.cirnoworks.uhs.Link;
import com.cirnoworks.uhs.LinkManager;
import com.cirnoworks.uhs.Protocal;

public class RedirectSublink extends Link {
	private long lastUpdateTime;
	private SocketAddress senderAddress;
	private ControlLink parent;
	private ByteBuffer buf = ByteBuffer.allocateDirect(65536);
	private final AddressKey addressKey = new AddressKey();

	public RedirectSublink(ControlLink parent, Selector selector,
			LinkManager manager, SocketAddress sendreAddress, int port)
			throws IOException {
		super(selector, manager, port);
		this.parent = parent;
		this.senderAddress = sendreAddress;
	}

	public SocketAddress getSenderAddress() {
		return senderAddress;
	}

	public void setSenderAddress(SocketAddress senderAddress) {
		this.senderAddress = senderAddress;
	}

	@Override
	public void sendData(Selector selector, SocketAddress address,
			ByteBuffer data) throws ClosedChannelException {
		lastUpdateTime = System.currentTimeMillis();
		super.sendData(selector, address, data);
	}

	public void sendData(Selector selector, ByteBuffer data)
			throws ClosedChannelException {
		addressKey.setAddress(data.getLong());
		addressKey.setPort(data.getChar());
		InetSocketAddress address = AddressCache.getAddress(addressKey);
		sendData(selector, address, data);
	}

	@Override
	protected void receiveData(Selector selector, SocketAddress from,
			ByteBuffer data) throws IOException {
		lastUpdateTime = System.currentTimeMillis();
		buf.clear();
		buf.put((byte) Protocal.RedirectPayload.OP);
		AddressCache.getAddress((InetSocketAddress) from, addressKey);
		buf.putLong(addressKey.getAddress());
		buf.putChar((char) addressKey.getPort());
		buf.put(data);
		buf.flip();
		parent.sendData(selector, senderAddress, buf);
	}

	public boolean isTimeout() {
		return System.currentTimeMillis() - lastUpdateTime > 300000;
	}

	@Override
	public void onClose() {

	}
}
